﻿Imports Microsoft.SharePoint
Imports Microsoft.SharePoint.Taxonomy
Imports Microsoft.SharePoint.Taxonomy.WebServices
Imports System.Text
Imports System.Globalization
Imports System.Reflection
Imports System.IO
Imports System.Management.Automation
Imports System.Management.Automation.Host
Imports System.Management.Automation.Runspaces
Imports System.Xml.Serialization
Imports System.Xml


Public Class ManagedMetadataExporter

    Private nameFirstTermSet As String = String.Empty

    Private _siteCollection As SPSite = Nothing
    Public ReadOnly Property SiteCollection() As SPSite
        Get
            If _siteCollection Is Nothing Then
                Try
                    _siteCollection = New SPSite(TextBox1.Text)
                Catch ex As Exception
                    MessageBox.Show("Error creating site: " & ex.Message)
                End Try
                Return _siteCollection
            Else
                Return _siteCollection
            End If
        End Get
    End Property


    Private _taxonomySession As TaxonomySession
    Public ReadOnly Property TaxSession() As TaxonomySession
        Get
            If _taxonomySession Is Nothing Then
                Try
                    _taxonomySession = New TaxonomySession(SiteCollection)
                Catch exc As Exception
                    MessageBox.Show("Error creating taxonomy session: " & exc.Message)
                End Try
                Return _taxonomySession
            Else
                Return _taxonomySession
            End If
        End Get
    End Property

#Region "Events"
    Private Sub btnGetTermStores_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetTermStores.Click
        GetTermStores()
    End Sub
    Private Sub btnGetGroups_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetGroups.Click
        GetGroups()
    End Sub
    Private Sub btnGetTermSets_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetTermSets.Click
        GetTermSets()
    End Sub
    Private Sub btnTerms_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTerms.Click
        GetTerms()
    End Sub
    Private Sub btnCreateTermSet_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCreateTermSet.Click
        CreateTermSet()
        GetTermSets()
    End Sub
    Private Sub btnDeleteTermSet_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDeleteTermSet.Click
        DeleteTermSet()
        GetTermSets()
    End Sub
    Private Sub btnExportTermSet_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExportTermSet.Click
        ExportTermSet()
    End Sub
    Private Sub btnImportTermSet_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnImportTermSet.Click
        ImportTermSet()
        GetTermSets()
    End Sub
    Private Sub btnDeleteTerm_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDeleteTerm.Click
        DeleteTerm()
        GetTerms()
    End Sub
    Private Sub btnCreateTerm_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCreateTerm.Click
        CreateTerm()
        GetTerms()
    End Sub
    Private Sub btnCreateTermInTermSet_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCreateTermInTermSet.Click
        CreateTermInTermSet()
        GetTerms()
    End Sub
    Private Sub btnAddTermSetToSearchSuggestion_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddTermSetToSearchSuggestion.Click
        AddTermSetToSearchSuggestionList()
    End Sub

    Private Sub btnAddTermToSearchSuggestion_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddTermToSearchSuggestion.Click
        AddTermToSearchSuggestionList()
    End Sub
#End Region

    '''Method that retrieve all term Stores and show all in TreeView
    Private Sub GetTermStores()
        'Clean TermStores treeView
        twTermStores.Nodes.Clear()

        If TextBox1.Text <> "" Then
            Dim session = TaxSession
            For Each tStore As TermStore In session.TermStores
                twTermStores.Nodes.Add(tStore.Id.ToString, tStore.Name)
            Next
        Else
            MessageBox.Show("You must enter site url")
        End If
    End Sub

    '''Method that retrieve groups
    Private Sub GetGroups()
        'Limpio el treeView
        tvGroups.Nodes.Clear()

        'Si hay algun TermStore seleccionado
        If twTermStores.SelectedNode IsNot Nothing Then
            Dim session = TaxSession
            For Each tStore As TermStore In session.TermStores
                If twTermStores.SelectedNode.Text = tStore.Name Then
                    For Each g As Group In tStore.Groups
                        If g.IsSiteCollectionGroup AndAlso ckSiteCollectionGroup.Checked = True Then
                            tvGroups.Nodes.Add(g.Id.ToString, g.Name)
                        ElseIf g.IsSystemGroup AndAlso ckSystemGroups.Checked = True Then
                            tvGroups.Nodes.Add(g.Id.ToString, g.Name)
                        ElseIf Not g.IsSiteCollectionGroup AndAlso Not g.IsSystemGroup Then
                            tvGroups.Nodes.Add(g.Id.ToString, g.Name)
                        End If
                    Next
                End If
            Next
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub

    '''Method that retrieve term sets
    Private Sub GetTermSets()
        'Clean treeView
        tvTermSets.Nodes.Clear()

        If twTermStores.SelectedNode IsNot Nothing Then
            If tvGroups.SelectedNode IsNot Nothing Then
                Dim session = TaxSession
                For Each tStore As TermStore In session.TermStores
                    If twTermStores.SelectedNode.Text = tStore.Name Then
                        For Each g As Group In tStore.Groups
                            If tvGroups.SelectedNode.Text = g.Name Then
                                For Each tSet As TermSet In g.TermSets
                                    tvTermSets.Nodes.Add(tSet.Id.ToString, tSet.Name)
                                Next
                            End If
                        Next
                    End If
                Next
            Else
                MessageBox.Show("You must select a Group")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If

    End Sub

    '''Method that create term set
    Private Sub CreateTermSet()
        If twTermStores.SelectedNode IsNot Nothing Then
            If tvGroups.SelectedNode IsNot Nothing Then
                Dim session = TaxSession
                For Each tStore As TermStore In session.TermStores
                    If twTermStores.SelectedNode.Text = tStore.Name Then
                        For Each g As Group In tStore.Groups
                            If tvGroups.SelectedNode.Text = g.Name Then
                                Dim name As String = ""
                                Dim dlg As New GetNameForm
                                If dlg.ShowDialog() = DialogResult.OK Then
                                    If dlg.txtName.Text <> "" Then
                                        name = dlg.txtName.Text
                                    Else
                                        MessageBox.Show("You must put a name")
                                    End If
                                End If
                                Try
                                    g.CreateTermSet(name)
                                    g.TermStore.CommitAll()
                                    MessageBox.Show("Term Set named " & dlg.txtName.Text & " is now created.")
                                Catch ex As Exception
                                    MessageBox.Show("Error creating termSet: " & ex.Message)
                                End Try
                            End If
                        Next
                    End If
                Next
            Else
                MessageBox.Show("You must select a Group")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub

    '''Method that delete term set
    Private Sub DeleteTermSet()
        If twTermStores.SelectedNode IsNot Nothing Then
            If tvTermSets.SelectedNode IsNot Nothing Then
                Dim session = TaxSession
                Dim termStore = session.TermStores(New Guid(twTermStores.SelectedNode.Name))
                Dim termset = termStore.GetTermSet(New Guid(tvTermSets.SelectedNode.Name))
                termset.Delete()
                termset.TermStore.CommitAll()
                MessageBox.Show("TermSet " & tvTermSets.SelectedNode.Text & " deleted")
            Else
                MessageBox.Show("You must select a TermSet")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub

    '''Method that export term set in csv file
    Private Sub ExportTermSet()
        If twTermStores.SelectedNode IsNot Nothing Then
            If tvGroups.SelectedNode IsNot Nothing Then
                If tvTermSets.SelectedNode IsNot Nothing Then
                    Dim saveFileDialog1 As New SaveFileDialog()
                    saveFileDialog1.Filter = "Managed Metadata File|*.csv"
                    saveFileDialog1.Title = "Save an CSV File"
                    saveFileDialog1.FileName = tvTermSets.SelectedNode.Text & ".csv"
                    If saveFileDialog1.ShowDialog() = DialogResult.OK Then
                        ' If the file name is not an empty string open it for saving.
                        If saveFileDialog1.FileName <> "" Then
                            Dim strFileName As String = saveFileDialog1.FileName
                            Dim myStream As StreamWriter = New StreamWriter(strFileName, False)
                            Dim exporter As New SolidQTermSetExporter
                            Dim session = TaxSession
                            Dim termStore = session.TermStores(New Guid(twTermStores.SelectedNode.Name))
                            Dim termset = termStore.GetTermSet(New Guid(tvTermSets.SelectedNode.Name))
                            Dim text As String = exporter.ExportTermSet(termset)
                            myStream.Write(text)
                            myStream.Close()
                            myStream = Nothing
                        End If
                    End If
                    MessageBox.Show("TermSet exported in " & saveFileDialog1.FileName)
                Else
                    MessageBox.Show("You must select a TermSet")
                End If
            Else
                MessageBox.Show("You must select a Group")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub



    '''Method that import term set from csv file
    Private Sub ImportTermSet()
        If twTermStores.SelectedNode IsNot Nothing Then
            If tvGroups.SelectedNode IsNot Nothing Then
                If tvGroups.SelectedNode IsNot Nothing Then
                    Dim openFileDialog1 As New OpenFileDialog()
                    openFileDialog1.Filter = "Managed Metadata File|*.csv"
                    openFileDialog1.Title = "Save an CSV File"
                    If openFileDialog1.ShowDialog() = DialogResult.OK Then
                        If openFileDialog1.FileName <> "" Then
                            Dim importManagerType As Type = GetType(ImportManager)
                            Dim parameterTypes As Type() = New Type(0) {GetType(TermStore)}
                            Dim constInfo As ConstructorInfo = importManagerType.GetConstructor(BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, CallingConventions.ExplicitThis, parameterTypes, Nothing)
                            Dim session As New TaxonomySession(SiteCollection)
                            Dim termStore As TermStore = session.TermStores(twTermStores.SelectedNode.Text)
                            Dim callParams As Object() = New Object(0) {termStore}
                            Dim importManager As ImportManager = DirectCast(constInfo.Invoke(callParams), ImportManager)
                            Dim reader As New StreamReader(openFileDialog1.FileName)
                            Dim group As Group = termStore.Groups(tvGroups.SelectedNode.Text)
                            Dim allTermsAdded As Boolean
                            Dim errorMessage As String = ""
                            importManager.ImportTermSet(group, reader, allTermsAdded, errorMessage)
                            If errorMessage <> "" Then
                                MessageBox.Show("Error message: " & errorMessage)
                            Else
                                MessageBox.Show("TermSet imported.")
                            End If

                        End If
                    End If
                Else
                    MessageBox.Show("You must select a Group")
                End If
            Else
                MessageBox.Show("You must select a Group")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub

    '''Method that create term in Term set
    Private Sub CreateTermInTermSet()
        If twTermStores.SelectedNode IsNot Nothing Then
            If tvGroups.SelectedNode IsNot Nothing Then
                Dim session = TaxSession
                Dim termStore = session.TermStores(New Guid(twTermStores.SelectedNode.Name))
                Dim termset = termStore.GetTermSet(New Guid(tvTermSets.SelectedNode.Name))
                Dim name As String = ""
                Dim dlg As New GetNameForm
                If dlg.ShowDialog() = DialogResult.OK Then
                    If dlg.txtName.Text <> "" Then
                        name = dlg.txtName.Text
                    Else
                        MessageBox.Show("You must put a name")
                    End If
                End If
                Try
                    termset.CreateTerm(name, 1033)
                    termset.TermStore.CommitAll()
                    MessageBox.Show("Term named " & dlg.txtName.Text & " is now created.")
                Catch ex As Exception
                    MessageBox.Show("Error creating term: " & ex.Message)
                End Try
            Else
                MessageBox.Show("You must select a Group")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub

    '''Method that retrieve terms
    Private Sub GetTerms()
        tvTerms.Nodes.Clear()
        If twTermStores.SelectedNode IsNot Nothing Then
            If tvGroups.SelectedNode IsNot Nothing Then
                If tvTermSets.SelectedNode IsNot Nothing Then
                    Dim session = TaxSession
                    For Each tStore As TermStore In session.TermStores
                        If twTermStores.SelectedNode.Text = tStore.Name Then
                            For Each g As Group In tStore.Groups
                                If tvGroups.SelectedNode.Text = g.Name Then
                                    For Each tSet As TermSet In g.TermSets
                                        If tvTermSets.SelectedNode.Text = tSet.Name Then
                                            For Each term As Term In tSet.Terms
                                                RecursiveTermChildGetter(term, 0)
                                            Next
                                        End If
                                    Next
                                End If
                            Next
                        End If
                    Next
                Else
                    MessageBox.Show("You must select a TermSet")
                End If
            Else
                MessageBox.Show("You must select a Group")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub

    Private Sub RecursiveTermChildGetter(ByVal t As Term, ByVal level As Integer)
        tvTerms.Nodes.Add(t.Id.ToString, t.Name)
        If t.Terms.Count > 0 Then
            For Each termChild As Term In t.Terms
                RecursiveTermChildGetter(termChild, level + 1)
            Next
        End If
    End Sub

    '''Method that deletes a term
    Private Sub DeleteTerm()
        If twTermStores.SelectedNode IsNot Nothing Then
            If tvGroups.SelectedNode IsNot Nothing Then
                If tvTermSets.SelectedNode IsNot Nothing Then
                    If tvTerms.SelectedNode IsNot Nothing Then
                        Dim session As New TaxonomySession(SiteCollection)
                        Dim term As Term = session.GetTerm(New Guid(tvTerms.SelectedNode.Name))
                        term.Delete()
                        term.TermStore.CommitAll()
                        MessageBox.Show("Term " & tvTerms.SelectedNode.Text & " deleted")
                    Else
                        MessageBox.Show("You must select a Term")
                    End If
                Else
                    MessageBox.Show("You must select a TermSet")
                End If
            Else
                MessageBox.Show("You must select a Group")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub

    '''Method that created a term
    Private Sub CreateTerm()
        If twTermStores.SelectedNode IsNot Nothing Then
            If tvGroups.SelectedNode IsNot Nothing Then
                If tvTermSets.SelectedNode IsNot Nothing Then
                    If tvTerms.SelectedNode IsNot Nothing Then
                        Dim session As New TaxonomySession(SiteCollection)
                        Dim term As Term = session.GetTerm(New Guid(tvTerms.SelectedNode.Name))

                        Dim name As String = ""
                        Dim dlg As New GetNameForm
                        If dlg.ShowDialog() = DialogResult.OK Then
                            If dlg.txtName.Text <> "" Then
                                name = dlg.txtName.Text
                            Else
                                MessageBox.Show("You must put a name")
                            End If
                        End If
                        Try
                            term.CreateTerm(name, 1033)
                            term.TermStore.CommitAll()
                            MessageBox.Show("Term named " & dlg.txtName.Text & " is now created.")
                        Catch ex As Exception
                            MessageBox.Show("Error creating term: " & ex.Message)
                        End Try
                    Else
                        MessageBox.Show("You must select a Term")
                    End If
                Else
                    MessageBox.Show("You must select a TermSet")
                End If
            Else
                MessageBox.Show("You must select a Group")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub

    '''Method that a TermSet to the Search Suggestions List
    Private Sub AddTermSetToSearchSuggestionList()
        ' List to feed with commands to execute with Powershell
        Dim listCommands As List(Of String) = New List(Of String)

        If twTermStores.SelectedNode IsNot Nothing Then
            If tvGroups.SelectedNode IsNot Nothing Then
                If tvTermSets.SelectedNode IsNot Nothing Then
                    Dim session = TaxSession
                    For Each tStore As TermStore In session.TermStores
                        If twTermStores.SelectedNode.Text = tStore.Name Then
                            For Each g As Group In tStore.Groups
                                If tvGroups.SelectedNode.Text = g.Name Then
                                    For Each tSet As TermSet In g.TermSets
                                        If tvTermSets.SelectedNode.Text = tSet.Name Then
                                            For Each term As Term In tSet.Terms
                                                'Add to the list of commands a new Query Suggestion to execute with Powershell
                                                listCommands.Add("New-SPEnterpriseSearchLanguageResourcePhrase -SearchApplication $ssa -Language en-US -Type QuerySuggestionAlwaysSuggest -Name " & """" & term.Name & """")
                                            Next
                                            ' Running script
                                            RunScript(listCommands)
                                            MessageBox.Show("TermSet " & tSet.Name & " correcty added to the Search Suggestions list.")
                                        End If
                                    Next
                                End If
                            Next
                        End If
                    Next
                Else
                    MessageBox.Show("You must select a TermSet")
                End If
            Else
                MessageBox.Show("You must select a Group")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub

    '''Method that a Term to the Search Suggestions List
    Private Sub AddTermToSearchSuggestionList()
        ' String to feed with the command to execute with Powershell
        Dim stringCommand As String = String.Empty

        If twTermStores.SelectedNode IsNot Nothing Then
            If tvGroups.SelectedNode IsNot Nothing Then
                If tvTermSets.SelectedNode IsNot Nothing Then
                    If tvTerms.SelectedNode IsNot Nothing Then
                        Dim session As New TaxonomySession(SiteCollection)
                        Dim term As Term = session.GetTerm(New Guid(tvTerms.SelectedNode.Name))
                        stringCommand = "New-SPEnterpriseSearchLanguageResourcePhrase -SearchApplication $ssa -Language en-US -Type QuerySuggestionAlwaysSuggest -Name " & """" & term.Name & """"
                        RunScript(stringCommand)
                        MessageBox.Show("Term " & term.Name & " correcty added to the Search Suggestions list.")
                    Else
                        MessageBox.Show("You must select a Term")
                    End If
                Else
                    MessageBox.Show("You must select a TermSet")
                End If
            Else
                MessageBox.Show("You must select a Group")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub

    ''' Method that executes a Powershell script which create a new phrases to the Search Suggestions List
    Private Sub RunScript(ByVal listCommands As List(Of String))
        ' Create Powershell runspace
        Dim runspace As Runspace = RunspaceFactory.CreateRunspace()
        ' Create the results
        Dim results As New System.Collections.ObjectModel.Collection(Of PSObject)
        ' Open it
        runspace.Open()

        ' Create a pipeline and feed it the script text
        Using pipeline As Pipeline = runspace.CreatePipeline()
            pipeline.Commands.AddScript("[System.Reflection.Assembly]::LoadWithPartialName(""Microsoft.SharePoint"")")
            pipeline.Commands.AddScript("Add-PSSnapin Microsoft.SharePoint.PowerShell")
            pipeline.Commands.AddScript("$ssa=Get-SPEnterpriseSearchServiceApplication")
            For Each command As String In listCommands
                pipeline.Commands.AddScript(command)
            Next
            pipeline.Commands.AddScript("$timer=Get-SPTimerJob|? {$_.Name -eq ""Prepare Query Suggestions""}")
            pipeline.Commands.AddScript("$timer.RunNow()")
            ' Invoke the cmdlet
            Try
                results = pipeline.Invoke()
            Catch ex As Exception
                Throw ex
            End Try
        End Using

        ' Close the runspace
        runspace.Close()
    End Sub

    ''' Method that executes a Powershell script which create a new phrases to the Search Suggestions List
    Private Sub RunScript(ByVal stringCommand As String)
        ' Create Powershell runspace
        Dim runspace As Runspace = RunspaceFactory.CreateRunspace()
        ' Create the results
        Dim results As New System.Collections.ObjectModel.Collection(Of PSObject)
        ' Open it
        runspace.Open()

        ' Create a pipeline and feed it the script text
        Using pipeline As Pipeline = runspace.CreatePipeline()
            pipeline.Commands.AddScript("[System.Reflection.Assembly]::LoadWithPartialName(""Microsoft.SharePoint"")")
            pipeline.Commands.AddScript("Add-PSSnapin Microsoft.SharePoint.PowerShell")
            pipeline.Commands.AddScript("$ssa=Get-SPEnterpriseSearchServiceApplication")
            pipeline.Commands.AddScript(stringCommand)
            pipeline.Commands.AddScript("$timer=Get-SPTimerJob|? {$_.Name -eq ""Prepare Query Suggestions""}")
            pipeline.Commands.AddScript("$timer.RunNow()")
            ' Invoke the cmdlet
            Try
                results = pipeline.Invoke()
            Catch ex As Exception
                Throw ex
            End Try
        End Using

        ' Close the runspace
        runspace.Close()
    End Sub

    '''Generate Terms levels
    'Private maxLevels As Integer = 0
    'Private currentLevel As Integer = 1
    'Private Sub btnCreateLevels_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCreateLevels.Click

    '    'Dim changeGroup As ChangedGroup
    '    Dim cts As ChangedItem


    '    Dim session As New TaxonomySession(SiteCollection)
    '    For Each tStore As TermStore In session.TermStores
    '        If twTermStores.SelectedNode.Text = tStore.Name Then
    '            For Each g As Group In tStore.Groups
    '                If tvGroups.SelectedNode.Text = g.Name Then
    '                    If g.TermSets.Count > 0 Then
    '                        Dim tSet As TermSet = Nothing
    '                        Try
    '                            tSet = g.TermSets("TestLevelsTermSet")
    '                        Catch ex As ArgumentOutOfRangeException
    '                        End Try

    '                        If tSet Is Nothing Then
    '                            g.CreateTermSet("TestLevelsTermSet")
    '                        Else
    '                            tSet.Delete()
    '                            g.CreateTermSet("TestLevelsTermSet")
    '                        End If
    '                        maxLevels = Integer.Parse(txtCreateLevels.Text)
    '                        Dim tSet2 As TermSet = g.TermSets("TestLevelsTermSet")
    '                        Dim auxterm = tSet2.CreateTerm("Nivel" & currentLevel, 1033)
    '                        CreateSubTerm(auxterm, currentLevel + 1)



    '                        'Dim s As String = tSet2.Export()
    '                        MessageBox.Show("Terms Created!!")
    '                    End If
    '                End If
    '            Next
    '        End If
    '    Next
    'End Sub


    'Sub CreateSubTerm(ByVal t As Term, ByVal level As Integer)
    '    If level <= maxLevels Then
    '        Dim auxterm As Term = t.CreateTerm("Level" & level, 1033)
    '        CreateSubTerm(auxterm, level + 1)
    '        'Hacemos el commit para que se creen todo los nodos
    '        t.TermStore.CommitAll()
    '    End If
    'End Sub

    Private Sub LinkLabel1_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles LinkLabel1.LinkClicked
        System.Diagnostics.Process.Start("www.solidq.com")
    End Sub

    Private Sub LinkLabel2_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles LinkLabel2.LinkClicked
        System.Diagnostics.Process.Start("http://blogs.solidq.com")
    End Sub


    Private Sub exportTermSetXML_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If twTermStores.SelectedNode IsNot Nothing Then
            If tvGroups.SelectedNode IsNot Nothing Then
                If tvTermSets.SelectedNode IsNot Nothing Then
                    Dim saveFileDialog1 As New SaveFileDialog()
                    saveFileDialog1.Filter = "Managed Metadata File|*.xml"
                    saveFileDialog1.Title = "Save an XML File"
                    saveFileDialog1.FileName = tvTermSets.SelectedNode.Text & ".xml"
                    If saveFileDialog1.ShowDialog() = DialogResult.OK Then
                        ' If the file name is not an empty string open it for saving.
                        If saveFileDialog1.FileName <> "" Then
                            Dim strFileName As String = saveFileDialog1.FileName
                            Dim myStream As StreamWriter = New StreamWriter(strFileName, False)
                            Dim exporter As New SolidQTermSetExporterXML
                            Dim session = TaxSession
                            Dim termStore = session.TermStores(New Guid(twTermStores.SelectedNode.Name))
                            Dim termset = termStore.GetTermSet(New Guid(tvTermSets.SelectedNode.Name))

                            ' Export terms in all languages
                            Dim _listTermSetXML As New List(Of TermSetXML)

                            Dim defaultlanguage = termset.TermStore.DefaultLanguage
                            For Each language In termset.TermStore.Languages.OrderByDescending(Function(t) t = defaultlanguage)
                                Dim _termSetNode As New List(Of TermXMLElement)
                                Dim _termSetInLanguages As New TermSetXML
                                _termSetInLanguages.TermSetLCID = language
                                _termSetInLanguages.TermSetDescription = termset.Description
                                _termSetInLanguages.Guid = termset.Id.ToString
                                termStore.WorkingLanguage = language

                                _termSetNode.Clear()
                                Dim cont As Integer = 0
                                For Each topTerm In termset.Terms.OrderBy(Function(t) t.Id)
                                    Dim _termListSynonymous As New List(Of TermXMLSynonymous)
                                    Dim labelCollection As LabelCollection = topTerm.GetAllLabels(language)
                                    Dim _term As New TermXMLElement

                                    For Each label In labelCollection
                                        Dim _termSynonymous As New TermXMLSynonymous
                                        If label.Value.Equals(topTerm.GetDefaultLabel(language)) Then
                                            _term.Name = label.Value
                                            _term.Guid = topTerm.Id.ToString
                                            _term.Description = topTerm.GetDescription(language)
                                        Else
                                            _termSynonymous.SynonymousName = label.Value
                                            _termListSynonymous.Add(_termSynonymous)
                                            _term.TermCollectionSynonymous = _termListSynonymous
                                        End If
                                    Next
                                    cont = cont + 1
                                    _termSetNode.Add(_term)
                                Next

                                _termSetInLanguages.TermSetName = termset.Name
                                _termSetInLanguages.TermSet = _termSetNode
                                _listTermSetXML.Add(_termSetInLanguages)
                            Next

                            Dim serializer As XmlSerializer = New XmlSerializer(GetType(SolidQTermSetExporterXML))
                            Dim exportXMLObj As SolidQTermSetExporterXML = New SolidQTermSetExporterXML()
                            exportXMLObj.TermSetInLanguages = _listTermSetXML
                            serializer.Serialize(myStream, exportXMLObj)

                            myStream.Close()
                            myStream = Nothing
                        End If
                    End If
                    MessageBox.Show("TermSet exported in " & saveFileDialog1.FileName)
                Else
                    MessageBox.Show("You must select a TermSet")
                End If
            Else
                MessageBox.Show("You must select a Group")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub


    Private Sub importTermSetXML_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        If twTermStores.SelectedNode IsNot Nothing Then
            If tvGroups.SelectedNode IsNot Nothing Then
                If tvGroups.SelectedNode IsNot Nothing Then
                    Dim openFileDialog1 As New OpenFileDialog()
                    openFileDialog1.Filter = "Managed Metadata File|*.xml"
                    openFileDialog1.Title = "Save an XML File"
                    If openFileDialog1.ShowDialog() = DialogResult.OK Then
                        If openFileDialog1.FileName <> "" Then
                            Dim xmlDoc As New XmlDocument
                            Dim xmlNodeListTermSets As XmlNodeList
                            Dim xmlNode As XmlNode
                            Dim contTerm As Integer = 0
                            Dim isLabel As Boolean = False

                            xmlDoc.Load(openFileDialog1.FileName)
                            xmlNodeListTermSets = xmlDoc.GetElementsByTagName("TermSetXML")
                            Dim cont As Integer = 0
                            Dim listAuxTerms As New List(Of Term)

                            ' recorremos los bloques
                            ' cada termset tendrá n bloques en
                            ' funcion de las traducciones que tenga
                            For Each xmlNode In xmlNodeListTermSets
                                Dim session = TaxSession

                                cont = cont + 1
                                Dim nameTermSet = xmlNode.ChildNodes(0).InnerText
                                Dim lcidTermSet = xmlNode.ChildNodes(1).InnerText
                                Dim descriptionTermSet = xmlNode.ChildNodes(2).InnerText
                                Dim listSynonymous As New List(Of String)
                                Dim i As Integer = xmlNode.ChildNodes(3).ChildNodes.Count

                                ' insertamos el TERMSET
                                If twTermStores.SelectedNode IsNot Nothing Then
                                    If tvGroups.SelectedNode IsNot Nothing Then

                                        For Each tStore As TermStore In session.TermStores
                                            If twTermStores.SelectedNode.Text = tStore.Name Then
                                                For Each g As Group In tStore.Groups
                                                    If tvGroups.SelectedNode.Text = g.Name Then
                                                        ' si es el primero creamos el termset
                                                        ' si no lo es, tendremos que recuperarlo y traducirlo
                                                        If cont = 1 Then
                                                            Try
                                                                Dim newTermSet As TermSet = g.CreateTermSet(nameTermSet, New Guid(xmlNode.Attributes("Guid").Value.ToString), Integer.Parse(lcidTermSet))
                                                                newTermSet.Description = descriptionTermSet
                                                                nameFirstTermSet = newTermSet.Name
                                                                newTermSet.TermStore.CommitAll()
                                                            Catch ex As Exception
                                                                MessageBox.Show("Error creating termSet: " & ex.Message)
                                                            End Try
                                                        Else
                                                            Dim termStore = session.TermStores(New Guid(twTermStores.SelectedNode.Name))
                                                            Dim termSetCreated As TermSet = g.TermSets(nameFirstTermSet)
                                                            termStore.WorkingLanguage = Integer.Parse(lcidTermSet)
                                                            termSetCreated.Name = nameTermSet
                                                            nameFirstTermSet = nameTermSet
                                                            termSetCreated.TermStore.CommitAll()
                                                        End If
                                                    End If
                                                Next
                                            End If
                                        Next
                                    End If
                                End If

                                contTerm = contTerm + 1
                                ' recorremos los terminos TERMS
                                For index As Integer = 0 To i - 1
                                    Dim nameTerm As String = xmlNode.ChildNodes(3).ChildNodes(index).Item("Name").InnerText
                                    Dim desciptionTerm As String = xmlNode.ChildNodes(3).ChildNodes(index).Item("Description").InnerText

                                    ' comprobamos si tiene sinónimos SYNONYMOUS
                                    listSynonymous.Clear()
                                    If xmlNode.ChildNodes(3).ChildNodes(index).ChildNodes(2) IsNot Nothing Then
                                        Dim numSynonymous As Integer = xmlNode.ChildNodes(3).ChildNodes(index).ChildNodes(2).ChildNodes.Count
                                        For index2 As Integer = 0 To numSynonymous - 1
                                            listSynonymous.Add(xmlNode.ChildNodes(3).ChildNodes(index).ChildNodes(2).ChildNodes(index2).Item("SynonymousName").InnerText)
                                        Next
                                    End If

                                    ' insertamos terminos y sinonimos en la admin central
                                    If twTermStores.SelectedNode IsNot Nothing Then
                                        If tvGroups.SelectedNode IsNot Nothing Then
                                            For Each tStore As TermStore In session.TermStores
                                                If twTermStores.SelectedNode.Text = tStore.Name Then
                                                    For Each g As Group In tStore.Groups
                                                        If tvGroups.SelectedNode.Text = g.Name Then
                                                            ' solo creamos términos con el primer bloque que leemos
                                                            ' el resto son etiquetas
                                                            If contTerm = 1 Then
                                                                Dim termSetCreated As TermSet = g.TermSets(nameTermSet)
                                                                Dim newTerm As Term = termSetCreated.CreateTerm(nameTerm, Integer.Parse(lcidTermSet), New Guid(xmlNode.ChildNodes(3).ChildNodes(index).Attributes("Guid").Value.ToString))
                                                                newTerm.SetDescription(desciptionTerm, Integer.Parse(lcidTermSet))
                                                                newTerm.TermStore.CommitAll()
                                                                'almacenamos los terminos originales
                                                                listAuxTerms.Add(newTerm)

                                                                ' comprobamos si este termino tiene sinonimos
                                                                For Each synonymous As String In listSynonymous
                                                                    newTerm.CreateLabel(synonymous, Integer.Parse(lcidTermSet), False)
                                                                Next
                                                                newTerm.TermStore.CommitAll()
                                                            Else
                                                                listAuxTerms(index).CreateLabel(nameTerm, Integer.Parse(lcidTermSet), True)
                                                                listAuxTerms(index).SetDescription(desciptionTerm, Integer.Parse(lcidTermSet))
                                                                listAuxTerms(index).TermStore.CommitAll()
                                                                For Each synonymous As String In listSynonymous
                                                                    listAuxTerms(index).CreateLabel(synonymous, Integer.Parse(lcidTermSet), False)
                                                                Next
                                                                listAuxTerms(index).TermStore.CommitAll()
                                                            End If
                                                        End If
                                                    Next
                                                End If
                                            Next
                                        End If
                                    End If
                                Next

                            Next
                            MessageBox.Show("TermSet imported")
                        End If
                    End If
                Else
                    MessageBox.Show("You must select a Group")
                End If
            Else
                MessageBox.Show("You must select a Group")
            End If
        Else
            MessageBox.Show("You must select a Term Store")
        End If
    End Sub
End Class
